package org.opu.pc.ui.client.widgets;

import java.awt.Color;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import org.opu.pc.ui.client.BeanView;

/**
 *
 * @author yura
 */
public class TabelBeanView extends JTable implements BeanView {

	private static final long serialVersionUID = -351134692342439361L;
	
	private Object head[];
	private Class<?>[] types;

    public TabelBeanView() {
        this(new String[][]{{}}, new Class<?>[]{}, new String[]{});
    }

    public TabelBeanView(final Object[][] rowData, Class<?>[] types, 
    		final Object[] columnNames) {
        super(new ModelImpl(columnNames, rowData));
        this.head = columnNames;
        this.types = types;
        setDragEnabled(false);
        setBackground(Color.WHITE);
        getTableHeader().setReorderingAllowed(false);
        setRowSelectionAllowed(true);
        setFillsViewportHeight(true);
        setRowSorter(new TableRowSorter<TableModel>(getModel()));
    }

    @Override
    public String getToolTipText(MouseEvent e) {
        int c = columnAtPoint(e.getPoint());
        int r = rowAtPoint(e.getPoint());

        if (c < 0 || r < 0) {
            return getToolTipText();
        }

        try {
            Object valueAt = getValueAt(r, c);

            if (valueAt == null) {
                return null;
            } else {
                return String.valueOf(valueAt);
            }
        } catch (Exception ex) {
            return getToolTipText();
        }
    }

    @Override
    protected JTableHeader createDefaultTableHeader() {
        return new JTableHeader(columnModel) {

			private static final long serialVersionUID = 1315738627825410157L;

			@Override
            public String getToolTipText(MouseEvent e) {
                int index = columnModel.getColumnIndexAtX(e.getPoint().x);
                int rIndex = columnModel.getColumn(index).getModelIndex();

                if (head.length > rIndex) {
                    Object hv = columnModel.getColumn(rIndex).getHeaderValue();

                    if (hv != null) {
                        return String.valueOf(hv);
                    } else {
                        return getToolTipText();
                    }
                } else {
                    return getToolTipText();
                }
            }
        };
    }
    
    @Override
    public Class<?> getColumnClass(int column) {
    	if(types[column] != null) {
    		return types[column];
    	} else {
    		return super.getColumnClass(column);
    	}
    }

    @Override
    public void setContent(Object[] columnNames, Class<?>[] types, 
    		Object[][] rowData) {
        this.head = columnNames;
        this.types = types;
        ((ModelImpl) getModel()).setContent(columnNames, rowData);
    }
    
    public Object[][] getContent(){
    	return ((ModelImpl) getModel()).rowData;
    }
    
    public void setEditable(boolean edit){
        ((ModelImpl) getModel()).editable = edit;
    }

    @Override
    public JComponent asComponent() {
        return this;
    }

    @Override
    public int[] getSelectedIndexes(){
        return getSelectedRows();
    }

    @Override
    public void addListSelectionListener(ListSelectionListener listener){
    	getSelectionModel().addListSelectionListener(listener);
    }

    /**
     * @see JTable#JTable(Object[][], Object[])
     */
    private static class ModelImpl extends AbstractTableModel {

		private static final long serialVersionUID = -5601748915104293860L;
		
		Object[] columnNames;
        Object[][] rowData;
        private boolean editable = false;

        public ModelImpl(Object[] columnNames, Object[][] rowData) {
            this.columnNames = columnNames;
            this.rowData = rowData;
        }

        final void setContent(Object[] columnNames, Object[][] rowData) {
            this.columnNames = columnNames;
            this.rowData = rowData;
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    fireTableStructureChanged();
                }
            });
        }

        @Override
        public String getColumnName(int column) {
            return columnNames[column].toString();
        }

        @Override
        public int getRowCount() {
            return rowData.length;
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public Object getValueAt(int row, int col) {
            return rowData[row][col];
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            return editable;
        }

        @Override
        public void setValueAt(Object value, int row, int col) {
            rowData[row][col] = value;
            fireTableCellUpdated(row, col);
        }
    }
}
